package com.xyzwps.collections.stack;

import java.util.Objects;

public class LinkedStack<E> implements Stack<E> {
    private Node<E> top = null;
    private int _size = 0;

    @Override
    public E push(E element) {
        Node<E> node = new Node<>(element, this.top);
        this._size++;
        this.top = node;
        return element;
    }

    @Override
    public E pop() {
        checkEmpty();

        Node<E> node = this.top;
        this.top = node.prev;
        this._size--;
        return node.element;
    }

    @Override
    public E peek() {
        checkEmpty();
        return this.top.element;
    }

    private void checkEmpty() {
        if (this.isEmpty()) {
            throw new IllegalStateException("Stack is EMPTY.");
        }
    }

    @Override
    public int size() {
        return this._size;
    }

    @Override
    public boolean isEmpty() {
        return this.size() == 0;
    }

    @Override
    public void clear() {
        this.top = null;
        this._size = 0;
    }

    @Override
    public boolean has(E element) {
        for (Node<E> curr = this.top; curr != null; curr = curr.prev) {
            if (Objects.equals(curr.element, element)) return true;
        }
        return false;
    }

    private static class Node<E> {
        E element;
        Node<E> prev;

        Node(E element, Node<E> prev) {
            this.element = element;
            this.prev = prev;
        }
    }
}
